package com.wx.api.pay.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.Date;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.wx.api.config.WxPayConfig;
import com.wx.api.pay.IPayService;
import com.wx.api.utils.SpringUtil;
import com.wx.api.utils.WxPayUtil;
import com.wx.model.dto.PayParameter;
import com.wx.model.dto.PrePayDto;
import com.wx.model.entity.WxOrder;
import com.wx.model.vo.PrePayVo;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 微信小程序支付实现类
 * 创建预支付订单流程
 * 1.请求code
 * 2.根据code拿到openId
 * 3.
 *
 * @author liaogui
 * @date 2023/12/09
 */
@Service("wxPayService")
public class WxPayServiceImpl implements IPayService {
    public static final Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);

    private WxPayConfig wxPayConfig;

    String privateKey = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCah8PGFSZJbLIx\n" +
            "6tpey69M/X3mW1nm2yxz+yR0vjtivRGPpbej7IhFzFwJ9vNKcsZejSNnL4c8fhSX\n" +
            "yB7pApHzjEOh/lMLDYh/EsF1KxipHFF6FD3l7h9ZARvxRPX+CakGj9J9TAhpMMT7\n" +
            "tJ263oGnM+VPWvMYKsH5U3ffahmojj7qjWMMZq9HcbohB9BmSoilIH+7eH0lO8pL\n" +
            "XURMvJa/EizTgvQAd3rnCDBtr2lfUtRZdHXbibCn1v+iRnmTbNaXtjbOI5IOGyfP\n" +
            "MBfjnxeT//BO5WSOYwesz0GxjDodNQGO58HNLpF9obYLe/0rRKQoxSbjpEimAjRA\n" +
            "07/mO6FvAgMBAAECggEAUpG8j/j5Dj6gMH/20rQvJQpF3XJuZSYzaH2HC0IiZS31\n" +
            "VjYMG/DlF7aMb16evOb7C8aKZjZFIpOT2U47BfIznlkSQlqscLl4d73D1SGD+ciB\n" +
            "2KM8N8G2yk4HajGY53at9C2hIQYhcGN4va3SoekGihr2qiJExmMCZoCtCpmcwCz8\n" +
            "68sDeiBv9la2LozzyY0RrmpwqN3H6FoJxxR4/g34WYjMKL/rRWSHkkivLryMK48Y\n" +
            "RGEmvXQOCsuYBF8D9/4fefBHc5gBz0hRiaToxh71w4n5scqnelu+CJgMOq62jkkC\n" +
            "1tU3Y/ffjkzbv5A4wU0TxdxnXQZSA+dajKRrddkHoQKBgQDJQMFRWa8/HXnLnS+/\n" +
            "N9ZSoduhox1XnvrDF+C0vubs5TTnw+o9fsXmqGholPoQHize2BaijPfGPw3xFPqd\n" +
            "f8cZ5DA4QV6Hc4SonTTag7Sxw8yjR2IUEYyY3nGUX+UqLnPRv2UKBnHs0R2DW5YG\n" +
            "qXpKJ7B28yClcbtsOgqB8FkQRwKBgQDEkT+2Xd8IAzQBe+HCJqeYUFmuGWuPc/am\n" +
            "X1GTB63vZHLrIVER0fM4dluTzMAWp6HyYVnEZ1UNSfeEQG0ISI9xouasVi27hhaV\n" +
            "/V8gsfxLcqgksQqfelBa3EyX94WDMp0189uvcsJKW78mVEhyr+RPixZuzpECF9uX\n" +
            "UuVuQHphmQKBgB4NF1DIbYylIByxWgHZmp04Ig2ex7Dfwl4DYMBciSryhtXcwUtx\n" +
            "dKeemgiTxktF1jloVujq18y4eaJ4GXwPKnHJSxH7YNwk+bgb0VqXtBGfRR1UeWa5\n" +
            "wB7LiHY5Y4TK7uxxAetfTv+nshp9QIe6ItKT3pvEbimGNBBTEmKYuxPdAoGBALiV\n" +
            "xQSVpei6SU3TbS6KafsoCO7qRA0T0lxtSgcNwRH6e8e9I4neY81zp49lSER96h/X\n" +
            "txouBrpR6TKx5TFQIhON65uN2agsxGzY30mumcKnyqmZ7uXPUEHiebKC50dKckLF\n" +
            "2lgpJbX57cgqgVXhQj5H2Cr5o0YZ7UVuvLAJsGKRAoGBAKUT2pQjvlLrw0tGAqaG\n" +
            "+ZrVReXyxSK5HZ1CQdu8pslmGNCmwTLAo/6YRgDoJC4RLpedqicRIzYNd25pt09w\n" +
            "y3OH3yq+Bsm4MBbKuaLDpAY2v8YFULlkZvOGfY2dqsJQIHict1ulKojx7DAOiw99\n" +
            "VzX38S8uR20EqmDvjiIVSfWC\n" +
            "-----END PRIVATE KEY-----";

    @Autowired
    public void setWxPayConfig(WxPayConfig wxPayConfig) {
        this.wxPayConfig = wxPayConfig;
    }

    public WxPayConfig getWxPayConfig() {
        return wxPayConfig;
    }

    @Override
    public boolean support(String type) {
        return SpringUtil.getBean(type) instanceof WxPayServiceImpl;
    }

    /**
     * 创建预付订单
     *
     * @param payParameter 支付参数
     * @return {@link PrePayVo }
     * @author liaogui
     */
    @Override
    public PrePayDto createPrepayOrder(PayParameter payParameter) throws Exception {
        // 1.校验当前商品参数是否正确


        // 2.生成系统订单ID 雪花算法
        String orderId = "";


        // 私钥
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
//        PrivateKey merchantPrivateKey = getWxPayConfig().getPrivateKey();
        //使用自动更新的签名验证器，不需要传入证书
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(wxPayConfig.getMchid(), new PrivateKeySigner(wxPayConfig.getMerchantSerialNumber(), merchantPrivateKey)),
                wxPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));

        CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(wxPayConfig.getMchid(), wxPayConfig.getMerchantSerialNumber(), merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier))
                .build();

        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid",wxPayConfig.getMchid())
                .put("appid", wxPayConfig.getAppId())
                .put("description", "测试商品")
                .put("notify_url", wxPayConfig.getNotifyUrl())
                .put("out_trade_no", "12312312312312312");
        rootNode.putObject("amount")
                .put("total",Integer.valueOf((String) payParameter.getPrice()))
                ;
        rootNode.putObject("payer")
                .put("openid", "u63v692qy08m4h1khj0pxxmn24yk0l1h");

        objectMapper.writeValue(bos, rootNode);

        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);

        String bodyAsString = EntityUtils.toString(response.getEntity());
        JSONObject jsonObject = JSONObject.parseObject(bodyAsString);

        logger.info("[WxPayUtils]生成的预支付ID:[{}]", jsonObject.get("prepay_id"));
        // 时间戳 秒
        String timestamp = System.currentTimeMillis() / 1000 + "";
        String noncestr = RandomStringUtils.randomNumeric(32);
        //  拼接签名
        StringBuilder builder = new StringBuilder();
        //小程序appId
        builder.append(wxPayConfig.getAppId()).append("\n");
        //时间戳
        builder.append(timestamp).append("\n");
        //随机字符串
        builder.append(noncestr).append("\n");
        //订单详情扩展字符串
        builder.append("prepay_id=").append(jsonObject.get("prepay_id")).append("\n");
        // 创建签名
        String sign = WxPayUtil.sign(builder.toString().getBytes(), merchantPrivateKey);
        JSONObject object = new JSONObject();
        object.put("timeStamp", timestamp);
        object.put("nonceStr", noncestr);
        object.put("package", "prepay_id=" +jsonObject.get("prepay_id"));
        // V3 版本 仅支持RSA
        object.put("signType", "RSA");
        object.put("paySign", sign);
        logger.info("[WxPayUtils]生成的支付参数:[{}]", object);
        // 异步创建预支付订单
        WxOrder wxOrder = new WxOrder();
        wxOrder.setId("");
        wxOrder.setGoodsId("");
        wxOrder.setGoodsName("");
        wxOrder.setOrderPrice("");
        wxOrder.setOpenId("");
        wxOrder.setMobile("");
        wxOrder.setPayType("");
        wxOrder.setOrderStatus("");
        wxOrder.setCreatedTime(new Date());
        wxOrder.setUpdatedTime(new Date());

        return null;


    }

    /**
     * kafka发送异步消息
     * @param wxOrder
     */
    private void asynCreateWxOrder(WxOrder wxOrder){

    }


}
